package com.xxx.controller;

import com.xxx.service.ZooKeeperService;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;

@Slf4j
@RestController
public class TestController {

    private int count = 0;

    @Autowired
    private ZooKeeperService zooKeeperService;

    /**
     * 添加zk节点
     * http://localhost:8081/addNode?path=/test1/1&data=11111111111111
     */
    @RequestMapping("/addNode")
    public String addNode(String path, String data) throws Exception {
        zooKeeperService.createNode(path, data);
        return "create zookeeper node success!";
    }

    /**
     * 修改zk节点
     * http://localhost:8081/addNode?path=/test1/1&data=2222222222222
     */
    @RequestMapping("/updateNode")
    public String updateNode(String path, String data) throws Exception {
        zooKeeperService.updateNode(path, data);
        return "update zookeeper node success!";
    }

    /**
     * 获取zk节点的值
     * http://localhost:8081/getNode?path=/test1/1
     */
    @RequestMapping("/getNode")
    public String getNode(String path) throws Exception {
        return zooKeeperService.getNodeData(path);
    }

    /**
     * 测试zk分布式锁
     * http://localhost:8081/testDistributeLock?path=/test_lock
     */
    @RequestMapping("/testDistributeLock")
    public String testDistributeLock(String path) throws Exception {
        // 声明锁对象，本质是zk临时有序节点
        InterProcessMutex mutex = zooKeeperService.getDistributeLock(path);

        // 模拟多线程对公共资源变量加锁
        for (int i = 0; i < 10; i++) {
            CompletableFuture.runAsync(() -> {
                // 分布式锁
                try {
                    // 获取互斥锁
                    mutex.acquire();

                    for (int j = 0; j < 10; j++) { // 模拟对公共的资源变量累加
                        count++;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    log.info("count = " + count);

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 释放互斥锁
                    try {
                        mutex.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        return "success";
    }

}
